/*!
 * \file scope.cpp
 */
#include "scope.h"
#include "tokens.h"

void CScope::addDefinition(const CSymbol& s)
{
  if(m_symbol.count(s))
    throw "symbol redefinition";

  m_symbol.insert(s);
}

void CScope::addReference(const CSymbol& s)
{
  if(m_symbol.count(s))
    return;

  if(s.m_type!=CSymbol::LABEL)
    throw "undefined symbol";
  else
    ++m_undef;
}

const CSymbol& CScope::getSymbol(int name) const
{
  CSymbol s(CSymbol::VARIABLE,name);

  if(m_symbol.count(s))
    return *m_symbol.find(s);

  throw "undefined symbol";
}

void CScope::dump() const
{
  for(std::set<CSymbol>::const_iterator it=m_symbol.begin();it!=m_symbol.end();++it)
  {
    printf("<");it->print();printf(">");
  }
}

CScope& getFrame()
{
  static CScope obj;
  return obj;
}


//////////////////////////////////////////////////////////////////////////////


void CSymbol::print() const
{
  static const char * const _t[]=
  {
    "BOOL",
    "INT",
    "FLOAT",
    "VECTOR",
    "VARIABLE",
    "LABEL",
  };

  printf("%s %s",_t[m_type],getIdentifier(m_name));

  if(m_sz)
    printf("[%d]",m_sz);
}

CSymbol CSymbol::makeByTypeAttr(int typeAttr,int name)
{
  switch(typeAttr)
  {
  case KEYWORD_BOOL:
    return CSymbol(BOOL,name);

  case KEYWORD_INT:
    return CSymbol(INT,name);

  case KEYWORD_FLOAT:
    return CSymbol(FLOAT,name);

  default:
    throw "unknown typeAttr";
  }
}

CSymbol CSymbol::makeTemp(Lang::Type type)
{
  static int tmpName;
  return CSymbol((CSymbol::Type)(type),--tmpName);
}
